﻿using System;

namespace GerbilLib
{
    /// <summary>
    /// Provides a Singleton Logger object so that log messages on the library level
    /// can be processed by anybody who listens to the log event.
    /// </summary>
    public class Logger
    {
        /// <summary>
        /// Event Handler for Log Message Event.
        /// </summary>
        public static event EventHandler<LogEventArgs> LogMessageEvent;

        /// <summary>
        /// Singleton Logger Object Instance
        /// </summary>
        private static readonly Logger instance = new Logger();

        /// <summary>
        /// Private constructor needed for Singleton pattern
        /// </summary>
        private Logger()
        {
            // Do nothing
        }

        /// <summary>
        /// Provides access to Singleton Logger Object instance
        /// </summary>
        public static Logger GetInstance
        {
            get { return instance; }
        }

        /// <summary>
        /// Fires a log message event with the specified message and logging level.
        /// If no logging level is specified the default Info will be used.
        /// </summary>
        /// <param name="message">Log message</param>
        /// <param name="loggingLevel">Logging level, used to separate warnings and errors from information or debug messages</param>
        public static void LogMessage(string message, LoggingLevel loggingLevel = LoggingLevel.Info)
        {
            GetInstance.OnLogMessage(new LogEventArgs(message, loggingLevel));
        }

        /// <summary>
        /// Fires the log message event to anybody listening to the event.
        /// </summary>
        /// <param name="e">Log message event arguments</param>
        protected virtual void OnLogMessage(LogEventArgs e)
        {
            EventHandler<LogEventArgs> handler = LogMessageEvent;
            if (handler != null) handler(this, e);
        }
    }

    /// <summary>
    /// Used to separate log messages into different categories. Levels are ordered by severity from highest to lowest.
    /// </summary>
    public enum LoggingLevel { Error, Warning, Info, Debug }

    /// <summary>
    /// Log message event argument object which is used when firing the LogMessage event.
    /// </summary>
    public class LogEventArgs : EventArgs
    {
        /// <summary>
        /// Log message
        /// </summary>
        public string Message { get; set; }
        /// <summary>
        /// Logging level
        /// </summary>
        public LoggingLevel LoggingLevel { get; set; }

        /// <summary>
        /// Constructor for log message event arguments object. Takes message
        /// and logging level as input parameters. If no log level is specified
        /// the default Info will be used.
        /// </summary>
        /// <param name="message">Log message</param>
        /// <param name="loggingLevel">Logging level</param>
        public LogEventArgs(string message, LoggingLevel loggingLevel = GerbilLib.LoggingLevel.Info)
        {
            Message = message;
            LoggingLevel = loggingLevel;
        }
    }
}
